#include <mpi.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
	int BUFFER_SIZE, BUFFER_TMP_SIZE;
	
	BUFFER_SIZE = 1024*4;
	char buffer[BUFFER_SIZE];
	int id, nproc, i, j, n, posicao, tag;
	
	posicao = 0;
	
	tag = 100;
	
	MPI_Status status;
	
	MPI_Init(&argc, &argv);
	MPI_Comm_rank(MPI_COMM_WORLD, &id);
	MPI_Comm_size(MPI_COMM_WORLD, &nproc);
	
	srand(time(0));

	int ORDEM = 2;

	float M[ORDEM][ORDEM];
	//BUFFER_SIZE = 0;
	
	//tamanho do numero que estara na coluna
	//MPI_Pack_size(ORDEM*ORDEM, MPI_FLOAT, MPI_COMM_WORLD, &BUFFER_TMP_SIZE);
    //BUFFER_SIZE = BUFFER_SIZE + BUFFER_TMP_SIZE;
    
    //tamanho reservado aos inteiros que serao enviados como posicao
    //MPI_Pack_size(ORDEM*ORDEM, MPI_INT, MPI_COMM_WORLD, &BUFFER_TMP_SIZE);
    //BUFFER_SIZE = BUFFER_SIZE + BUFFER_TMP_SIZE;

	//buffer = (char*) malloc(BUFFER_SIZE * 2 * sizeof(char));

	for(i = 0; i < ORDEM; i++){
		for(j = 0; j < ORDEM; j++){
			int r = rand();
			if(r%3 == 0){
				M[i][j] = r/100.0;
			} else {
				M[i][j] = 0;
			}
		}
	}	

	if(id == 0)
	{
		for(i = 0; i < ORDEM; i++){
			for(j = 0; j < ORDEM; j++){
				if(M[i][j] > 0){
					float dado = M[i][j];
					MPI_Pack(&dado, 1, MPI_FLOAT, &buffer, 100, &posicao, MPI_COMM_WORLD);
					MPI_Pack(&i, 1, MPI_INT, &buffer, 100, &posicao, MPI_COMM_WORLD);
					MPI_Pack(&j, 1, MPI_INT, &buffer, 100, &posicao, MPI_COMM_WORLD);
					
					printf("Enviando dado %f\n", dado);
				}
			}
		}
			
		for(n = 1; n < nproc; n++)
		{
			MPI_Send(buffer, BUFFER_SIZE, MPI_CHAR, n, tag, MPI_COMM_WORLD);
		}
	}
	else
	{
		posicao = 0;
		MPI_Recv(buffer, BUFFER_SIZE, MPI_PACKED, 0, tag, MPI_COMM_WORLD, &status);
		float dado;
		MPI_Unpack(buffer, BUFFER_SIZE, &posicao, &dado, 1, MPI_FLOAT, MPI_COMM_WORLD);
		printf("Dado recebido da matriz %f \n", dado);
	}
	printf("Sou o processo %i: %s \n", id, buffer);
	MPI_Finalize();
}
